package ee.ut.veebirakendus.servlet;

import java.io.BufferedReader;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
import org.json.JSONObject;

import ee.ut.veebirakendus.bot.ChatBot;
import ee.ut.veebirakendus.bot.ChatThread;
import ee.ut.veebirakendus.engine.GameEngine;

/**
 * Servlet implementation class PokerServlet
 */
public class PokerServlet extends WebSocketServlet {
	private static final long serialVersionUID = 1L;
	private Logger log;
	public static String SERVLET_NAME = "PokerServlet";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public PokerServlet() {
		super();
	}

	@Override
	public void init() throws ServletException {
		super.init();
		log = Logger.getLogger(SERVLET_NAME);
		log.info("PokerServlet initialized");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession(true);
		response.setContentType("text/plain");
		JSONObject jsonReq = parseRequest(request.getReader());
		log.debug("Message received: " + jsonReq);
		GameEngine engine = (GameEngine) session.getAttribute("engine");
		if (engine == null) {
			log.info("New session created, id: " + session.getId());
			engine = new GameEngine();
		}
		engine.doAction(jsonReq);
		engine.sendResponse(response);
		session.setAttribute("engine", engine);
	}

	private JSONObject parseRequest(BufferedReader reader) {
		String line;
		StringBuilder stringBuilder = new StringBuilder();
		JSONObject request = new JSONObject();
		try {
			while ((line = reader.readLine()) != null) {
				stringBuilder.append(line);
				log.debug("Reader line: " + line);
			}
			String[] pairs = stringBuilder.toString().split("&");
			for (String keyValuePair : pairs) {
				if (keyValuePair.contains("=")) {
					String[] pair = keyValuePair.split("=");
					request.put(pair[0], pair[1]);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return request;
	}

	@Override
	public WebSocket doWebSocketConnect(HttpServletRequest request,
			String paramString) {
		HttpSession session = request.getSession(true);
		ChatSocket chatSocket = new ChatSocket(
				(GameEngine) session.getAttribute("engine"));
		session.setAttribute("chat", chatSocket);
		log.info("ChatSocket instance created, sessionId: " + session.getId());
		// TODO sessiooni osa yle vaadata
		return chatSocket;
	}

	public class ChatSocket implements WebSocket.OnTextMessage {
		private Connection connection;
		private GameEngine engine;
		private ChatThread chatThread;

		public ChatSocket(GameEngine engine) {
			this.engine = engine;
		}

		@Override
		public void onOpen(Connection connection) {
			log.info("ChatSocket connection opened");
			this.connection = connection;
			chatThread = new ChatThread(this);
		}

		@Override
		public void onMessage(String arg0) {
			sendMessage();
		}

		public synchronized void sendMessage() {
			log.debug("Custom sendMessage() called");
			String message = new StringBuilder(engine.getRandomPlayerName())
					.append(":").append(ChatBot.getRandomExpression())
					.toString();
			log.info("Send ChatMessage: " + message);
			try {
				connection.sendMessage(message);
				log.info("ChatMessage sent");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onClose(int arg0, String arg1) {
			log.debug("ChatWebSocket onClose called, chatThread will be stopped");
			if (chatThread != null) {
				chatThread.stop();
			}
		}
	}
}
